import { AnyObj } from '@/interface/index';

/**
 * 处理 new Date(string | number) 在firefox 和 ie 上兼容问题
 * @param {string | number} str
 */
export const newDate = (str: string | number): Date => {
  if (isNaN(new Date(str).getTime())) {
    const arr: string[] = str.toString().split(' ');
    const d: string[] = arr[0].split('-');
    const t: string[] = arr[1].split(':');
    const date = new Date();
    date.setUTCFullYear(
      parseInt(d[0], 0),
      parseInt(d[1], 0) - 1,
      parseInt(d[2], 0),
    );
    date.setUTCHours(
      parseInt(t[0], 0),
      parseInt(t[1], 0),
      parseInt(t[2], 0),
      0,
    );
    return date;
  } else {
    return new Date(str);
  }
}

/**
 * 时间类型转换 默认返回格式'{y}-{m}-{d} {h}:{i}:{s}'
 * @param {(Object|string|number)} time
 * @param {string} cFormat 返回格式 {a}周几
 * @returns {string | null}
 */
export const parseTime = (
  time?: object | string | number,
  cFormat?: string,
): string | null => {
  if (time === undefined) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date: Date;
  if (typeof time === 'object') {
    date = time as Date;
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        time = parseInt(time, 0);
      } else {
        time = time.replace(new RegExp(/-/gm), '/');
      }
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj: { [key: string]: number } = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  };
  const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    if (key === 'a') {
      return ['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'][value];
    }
    return value.toString().padStart(2, '0');
  });
  return timeStr;
};

/**
 * 时间距离
 * @param {number} time 毫秒数
 * @param {srting} cFormat 大于一天事件格式 默认'{y}-{m}-{d}'
 * @returns {string}
 */
export const formatTime = (time: number, cFormat?: string) => {
  if (('' + time).length === 10) {
    time = parseInt(time + '', 0) * 1000;
  } else {
    time = +time;
  }
  const Od: Date = newDate(time);
  const d: number = Od.getTime();
  const now: number = Date.now();
  const diff: number = (now - d) / 1000;

  if (diff < 30) {
    return 'Just now';
  } else if (diff < 3600) {
    return Math.ceil(diff / 60) + 'mins';
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + 'hrs';
  } else if (diff < 3600 * 24 * 2) {
    return '1day';
  }

  return parseTime(time, cFormat || '{y}-{m}-{d}');
}

// Format and filter json data using filterKeys array
export const formatJson = (filterKeys: any, jsonData: any) => {
  jsonData.map((data: any) =>
    filterKeys.map((key: string) => {
      if (key === 'timestamp') {
        return parseTime(data[key]);
      } else {
        return data[key];
      }
    }),
  );
};

// Check if an element has a class
export const hasClass = (ele: HTMLElement, className: string) => {
  return !!ele.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
};

// Add class to element
export const addClass = (ele: HTMLElement, className: string) => {
  if (!hasClass(ele, className)) { ele.className += ' ' + className; }
};

// Remove class from element
export const removeClass = (ele: HTMLElement, className: string) => {
  if (hasClass(ele, className)) {
    const reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
  }
};

// Toggle class for the selected element
export const toggleClass = (ele: HTMLElement, className: string) => {
  if (!ele || !className) {
    return;
  }
  let classString = ele.className;
  const nameIndex = classString.indexOf(className);
  if (nameIndex === -1) {
    classString += '' + className;
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length);
  }
  ele.className = classString;
};

/**
 * html2Text
 * @param {string} val
 * @returns {string}
 */
export const html2Text = (val: string): string => {
  const div: HTMLDivElement = document.createElement('div');
  div.innerHTML = val;
  return div.textContent || div.innerText;
};

/**
 * deepClone 深克隆
 * @param {Object} source
 * @returns {Object}
 */
export const deepClone = (source: AnyObj) => {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments deepClone');
  }
  const targetObj: AnyObj = {};
  Object.keys(source).forEach((keys) => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys]);
    } else {
      targetObj[keys] = source[keys];
    }
  });
  return targetObj;
};

/**
 * number 转换为两位小数 string
 * @param {Object} source
 * @returns {string}
 */
export const toFixed2 = (num: number): string => {
  return parseFloat(num.toFixed(2)).toLocaleString();
};
